home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / alpha.arc / MAIN.C < prev    next >
C/C++ Source or Header  |  1988-07-26  |  21KB  |  917 lines

  1. /* Main network program - provides both client and server functions */
  2.  
  3. #define HOSTNAMELEN 32        /* changed from 16 by Bdale 860812 */
  4.  
  5. extern char startup[];    /* File to read startup commands from */
  6.  
  7. #include <stdio.h>
  8. #include "config.h"
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "netuser.h"
  12. #include "timer.h"
  13. #include "icmp.h"
  14. #include "iface.h"
  15. #include "ip.h"
  16. #include "tcp.h"
  17. #include "ax25.h"
  18. #include "netrom.h"
  19. #include "ftp.h"
  20. #include "telnet.h"
  21. #include "remote.h"
  22. #include "session.h"
  23. #include "cmdparse.h"
  24.  
  25. #ifdef    ASY
  26. #include "asy.h"
  27. #include "slip.h"
  28. #endif
  29.  
  30. #ifdef    NRS
  31. #include "nrs.h"
  32. #endif
  33.  
  34. #ifdef UNIX        /* BSD or SYS5 */
  35. #include "unix.h"
  36. #endif
  37.  
  38. #ifdef AMIGA
  39. #include "amiga.h"
  40. #endif
  41.  
  42. #ifdef MAC
  43. #include "mac.h"
  44. #endif
  45.  
  46. #ifdef MSDOS
  47. #include "asy.h"
  48. #endif
  49.  
  50. #ifdef    TRACE
  51. #include "trace.h"
  52. /* Dummy structure for loopback tracing */
  53. struct interface loopback = { NULLIF, "loopback" };
  54. #endif
  55.  
  56. extern struct interface *ifaces;
  57. extern char version[];
  58. extern struct mbuf *loopq;
  59.  
  60. int mode;
  61. FILE *logfp;
  62. char badhost[] = "Unknown host %s\n";
  63. char hostname[HOSTNAMELEN];    
  64. unsigned nsessions = NSESSIONS;
  65. int32 resolve();
  66. int16 lport = 1001;
  67. char prompt[] = "net> ";
  68. char nospace[] = "No space!!\n";    /* Generic malloc fail message */
  69.  
  70.  
  71. #ifndef    MSDOS            /* PC uses F-10 key always */
  72. static char escape = 0x1d;    /* default escape character is ^] */
  73. #endif
  74.  
  75. /* Command lookup and branch table */
  76. int go(),doax25(),cmdmode(),doconnect(),dotelnet(),doexit(),doclose(),
  77.     dohostname(),doreset(),dotcp(),dotrace(),doescape(),dohelp(),
  78.     doroute(),doecho(),dolog(),doip(),doetherstat(),
  79.     memstat(),doarp(),dosession(),doftp(),dostart(),dostop(),doattach(),
  80.     dosmtp(),doudp(),doparam(),doeol(),dohapnstat(),
  81.     doegstat(),dodump(),dorecord(),doupload(),dokick(),domode(),doshell(),
  82.     dodir(),docd(),doatstat(),doping(),doforward(),doremote(),donetrom(),
  83.     donrstat();
  84.  
  85. static struct cmds cmds[] = {
  86.     /* The "go" command must be first */
  87.     "",        go,        0, NULLCHAR,    NULLCHAR,
  88.     "!",        doshell,    0, NULLCHAR,    NULLCHAR,
  89. #if    (defined(MAC) && defined(APPLETALK))
  90.     "applestat",    doatstat,    0,    NULLCHAR,    NULLCHAR,
  91. #endif
  92. #if    (defined(AX25) || defined(ETHER) || defined(APPLETALK))
  93.     "arp",        doarp,        0, NULLCHAR,    NULLCHAR,
  94. #endif
  95. #ifdef    AX25
  96.     "ax25",        doax25,        0, NULLCHAR,    NULLCHAR,
  97. #endif    
  98.     "attach",    doattach,    2,
  99.         "attach <hardware> <hw specific options>", NULLCHAR,
  100. /* This one is out of alpabetical order to allow abbreviation to "c" */
  101. #ifdef    AX25
  102.     "connect",    doconnect,    3,"connect <interface> <callsign> [digipeaters]",
  103.         NULLCHAR,
  104. #endif
  105. #ifndef UNIX    /* BSD or SYS5 */
  106.     "cd",        docd,        0, NULLCHAR,    NULLCHAR,
  107. #endif
  108.     "close",    doclose,    0, NULLCHAR,    NULLCHAR,
  109.     "disconnect",    doclose,    0, NULLCHAR,    NULLCHAR,
  110.     "dir",        dodir,        0, NULLCHAR,    NULLCHAR,
  111. #ifdef    EAGLE
  112.     "eaglestat",    doegstat,    0, NULLCHAR,    NULLCHAR,
  113. #endif
  114.     "echo",        doecho,        0, NULLCHAR,    "echo [refuse|accept]",
  115.     "eol",        doeol,        0, NULLCHAR,
  116.         "eol options: unix, standard",
  117. #ifndef    MSDOS
  118.     "escape",    doescape,    0, NULLCHAR,    NULLCHAR,   
  119. #endif
  120. #ifdef    PC_EC
  121.     "etherstat",    doetherstat,    0, NULLCHAR,    NULLCHAR,
  122. #endif  PC_EC
  123.     "exit",        doexit,        0, NULLCHAR,    NULLCHAR,
  124.     "forward",    doforward,    0, NULLCHAR,    NULLCHAR,
  125.     "ftp",        doftp,        2, "ftp <address>",    NULLCHAR,
  126. #ifdef HAPN
  127.     "hapnstat",    dohapnstat,    0, NULLCHAR,    NULLCHAR,
  128. #endif HAPN
  129.     "help",        dohelp,        0, NULLCHAR,    NULLCHAR,
  130.     "hostname",    dohostname,    0, NULLCHAR,    NULLCHAR,
  131.     "kick",        dokick,        0, NULLCHAR,    NULLCHAR,
  132.     "log",        dolog,        0, NULLCHAR,    NULLCHAR,
  133.     "ip",        doip,        0, NULLCHAR,    NULLCHAR,
  134.     "memstat",    memstat,    0, NULLCHAR,    NULLCHAR,
  135. #ifdef    AX25
  136.     "mode",        domode,        2, "mode <interface>",    NULLCHAR,
  137. #endif
  138. #ifdef    NETROM
  139.     "netrom",    donetrom,    0, NULLCHAR,    NULLCHAR,
  140. #ifdef    NRS
  141.     "nrstat",    donrstat,    0, NULLCHAR,    NULLCHAR,
  142. #endif
  143. #endif
  144.     "param",    doparam,    2, "param <interface>", NULLCHAR,
  145.     "ping",        doping,        0, NULLCHAR,    NULLCHAR,
  146. #ifndef UNIX /* BSD or SYS5 */
  147.     "pwd",        docd,        0, NULLCHAR,    NULLCHAR,
  148. #endif
  149.     "record",    dorecord,    0, NULLCHAR,    NULLCHAR,
  150.     "remote",    doremote,    4, "remote <address> <port> <command>",
  151.                             NULLCHAR,
  152.     "reset",    doreset,    0, NULLCHAR,    NULLCHAR,
  153.     "route",    doroute,    0, NULLCHAR,    NULLCHAR,
  154.     "session",    dosession,    0, NULLCHAR,    NULLCHAR,
  155.     "shell",    doshell,    0, NULLCHAR,    NULLCHAR,
  156.     "smtp",        dosmtp,        0, NULLCHAR,    NULLCHAR,
  157. #ifdef    SERVERS
  158.     "start",    dostart,    2, "start <servername>",NULLCHAR,
  159.     "stop",        dostop,        2, "stop <servername>",    NULLCHAR,
  160. #endif
  161.     "tcp",        dotcp,        0, NULLCHAR,    NULLCHAR,
  162.     "telnet",    dotelnet,    2, "telnet <address>",    NULLCHAR,
  163. #ifdef    TRACE
  164.     "trace",    dotrace,    0, NULLCHAR,    NULLCHAR,
  165. #endif
  166.     "udp",        doudp,        0, NULLCHAR,    NULLCHAR,
  167.     "upload",    doupload,    0, NULLCHAR,    NULLCHAR,
  168.     "?",        dohelp,        0, NULLCHAR,    NULLCHAR,
  169.     NULLCHAR,    NULLFP,        0,
  170.         "Unknown command; type \"?\" for list",   NULLCHAR, 
  171. };
  172.  
  173. #ifdef    SERVERS
  174. /* "start" and "stop" subcommands */
  175. int dis1(),echo1(),ftp1(),smtp1(),tn1(),rem1();
  176. static struct cmds startcmds[] = {
  177.     "discard",    dis1,        0, NULLCHAR, NULLCHAR,
  178.     "echo",        echo1,        0, NULLCHAR, NULLCHAR,
  179.     "ftp",        ftp1,        0, NULLCHAR, NULLCHAR,
  180.     "smtp",        smtp1,        0, NULLCHAR, NULLCHAR,
  181.     "telnet",    tn1,        0, NULLCHAR, NULLCHAR,
  182.     "remote",    rem1,        0, NULLCHAR, NULLCHAR,
  183.     NULLCHAR,    NULLFP,        0,
  184.         "start options: discard, echo, ftp, smtp, telnet", NULLCHAR,
  185. };
  186. int ftp_stop(),smtp_stop(),echo_stop(),dis_stop(),tn_stop();
  187. int dis0(),echo0(),ftp0(),smtp0(),tn0(),rem0();
  188. static struct cmds stopcmds[] = {
  189.     "discard",    dis0,        0, NULLCHAR, NULLCHAR,
  190.     "echo",        echo0,        0, NULLCHAR, NULLCHAR,
  191.     "ftp",        ftp0,        0, NULLCHAR, NULLCHAR,
  192.     "smtp",        smtp0,        0, NULLCHAR, NULLCHAR,
  193.     "telnet",    tn0,        0, NULLCHAR, NULLCHAR,
  194.     "remote",    rem0,        0, NULLCHAR, NULLCHAR,
  195.     NULLCHAR,    NULLFP,        0,
  196.         "stop options: discard, echo, ftp, smtp, telnet",  NULLCHAR,
  197. };
  198. #endif
  199.  
  200. main(argc,argv)
  201. int argc;
  202. char *argv[];
  203. {
  204.     static char inbuf[BUFSIZ];    /* keep it off the stack */
  205.     int c;
  206.     char *ttybuf,*fgets();
  207.     int16 cnt;
  208.     int ttydriv();
  209.     int cmdparse();
  210.     void check_time(),ip_recv();
  211.     FILE *fp;
  212.     struct interface *ifp;
  213.     struct mbuf *bp;
  214.  
  215.     ioinit();
  216. #if    (defined(UNIX) || defined(AMIGA) || defined(MAC))
  217. #else
  218.     chktasker();
  219. #endif
  220. #ifdef    MSDOS
  221.     printf("KA9Q Internet Protocol Package, v%s DS = %x\n",version,
  222.         getds());
  223. #else
  224.     printf("KA9Q Internet Protocol Package, v%s\n",version);
  225. #endif
  226.     printf("Copyright 1988 by Phil Karn, KA9Q\n");
  227.     sessions = (struct session *)calloc(nsessions,sizeof(struct session));
  228.     if(argc > 1){
  229.         /* Read startup file named on command line */
  230.         fp = fopen(argv[1],"r");
  231.     } else {
  232.         fp = fopen(startup,"r");
  233.     }
  234.     if(fp != NULLFILE){
  235.         while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  236.             cmdparse(cmds,inbuf);
  237.         }
  238.         fclose(fp);
  239.     }        
  240.     cmdmode();
  241.  
  242.     /* Main commutator loop */
  243.     for(;;){
  244.         /* Process any keyboard input */
  245.         while((c = kbread()) != -1){
  246. #ifdef    MSDOS
  247.             /* c == -2 means the command escape key (F10) */
  248.             if(c == -2){
  249.                 if(mode != CMD_MODE){
  250.                     printf("\n");
  251.                     cmdmode();
  252.                 }
  253.                 continue;
  254.             }
  255. #endif
  256. #ifdef SYS5
  257.             if(c == escape && escape != 0){
  258.                 if(mode != CMD_MODE){
  259.                     printf("\r\n");
  260.                     cmdmode();
  261.                 }
  262.                 continue;
  263.             }
  264. #endif     /* SYS5 */
  265.             if((cnt = ttydriv(c,&ttybuf)) == 0)
  266.                 continue;
  267.             switch(mode){
  268.             case CMD_MODE:
  269.                 (void)cmdparse(cmds,ttybuf);
  270.                 fflush(stdout);
  271.                 break;
  272.             case CONV_MODE:
  273. #ifndef    MSDOS
  274.                 if(ttybuf[0] == escape && escape != 0){
  275.                     printf("\n");
  276.                     cmdmode();
  277.                 } else
  278. #endif MSDOS
  279.                     if(current->parse != NULLFP)
  280.                         (*current->parse)(ttybuf,cnt);
  281.  
  282.                 break;
  283.             }
  284.             if(mode == CMD_MODE){
  285.                 printf(prompt);
  286.                 fflush(stdout);
  287.             }
  288.         }
  289.         /* Service the loopback queue */
  290.         if((bp = dequeue(&loopq)) != NULLBUF){
  291.             struct ip ip;
  292. #ifdef    TRACE
  293.             dump(&loopback,IF_TRACE_IN,TRACE_IP,bp);        
  294. #endif
  295.             /* Extract IP header */
  296.             ntohip(&ip,&bp);
  297.             ip_recv(&ip,bp,0);
  298.         }
  299.         /* Service the interfaces */
  300.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next){
  301.             if(ifp->recv != NULLVFP)
  302.                 (*ifp->recv)(ifp);
  303.         }
  304.  
  305.         /* Service the clock if it has ticked */
  306.         check_time();
  307.  
  308. #ifdef    MSDOS
  309.         /* Tell DoubleDos to let the other task run for awhile.
  310.          * If DoubleDos isn't active, this is a no-op
  311.          */
  312.         giveup();
  313. #else
  314.         /* Wait until interrupt, then do it all over again */
  315.         eihalt();
  316. #endif
  317.     }
  318. }
  319. /* Standard commands called from main */
  320.  
  321. /* Enter command mode */
  322. int
  323. cmdmode()
  324. {
  325.     if(mode != CMD_MODE){
  326.         mode = CMD_MODE;
  327.         cooked();
  328.         printf(prompt);
  329.         fflush(stdout);
  330.     }
  331.     return 0;
  332. }
  333. static
  334. doexit(argc,argv)
  335. int argc;
  336. char *argv[];
  337. {
  338.     if(logfp != NULLFILE)
  339.         fclose(logfp);
  340.     iostop();
  341.     exit(0);
  342. }
  343. static
  344. dohostname(argc,argv)
  345. int argc;
  346. char *argv[];
  347. {
  348.     char *strncpy();
  349.  
  350.     if(argc < 2)
  351.         printf("%s\n",hostname);
  352.     else 
  353.         strncpy(hostname,argv[1],HOSTNAMELEN);
  354.     return 0;
  355. }
  356. static
  357. int
  358. dolog(argc,argv)
  359. int argc;
  360. char *argv[];
  361. {
  362.     char *strncpy();
  363.  
  364.     static char logname[15];
  365.     if(argc < 2){
  366.         if(logfp)
  367.             printf("Logging to %s\n",logname);
  368.         else
  369.             printf("Logging off\n");
  370.         return 0;
  371.     }
  372.     if(logfp){
  373.         fclose(logfp);
  374.         logfp = NULLFILE;
  375.     }
  376.     if(strcmp(argv[1],"stop") != 0){
  377.         strncpy(logname,argv[1],15);
  378.         logfp = fopen(logname,"a+");
  379.     }
  380.     return 0;
  381. }
  382. static
  383. int
  384. dohelp(argc,argv)
  385. int argc;
  386. char *argv[];
  387. {
  388.     register struct cmds *cmdp;
  389.     int i,j;
  390.  
  391.     printf("Main commands:\n");
  392.     for(i=0,cmdp = cmds;cmdp->name != NULL;cmdp++,i++){
  393.         printf("%s",cmdp->name);
  394.         if((i % 4) == 3)
  395.             printf("\n");
  396.         else {
  397.             for(j=strlen(cmdp->name);j < 16; j++)
  398.                 putchar(' ');
  399.         }
  400.     }
  401.     if((i % 4) != 0)
  402.         printf("\n");
  403.     return 0;
  404. }
  405.  
  406. doecho(argc,argv)
  407. int argc;
  408. char *argv[];
  409. {
  410.     extern int refuse_echo;
  411.  
  412.     if(argc < 2){
  413.         if(refuse_echo)
  414.             printf("Refuse\n");
  415.         else
  416.             printf("Accept\n");
  417.     } else {
  418.         if(argv[1][0] == 'r')
  419.             refuse_echo = 1;
  420.         else if(argv[1][0] == 'a')
  421.             refuse_echo = 0;
  422.         else
  423.             return -1;
  424.     }
  425.     return 0;
  426. }
  427. /* set for unix end of line for remote echo mode telnet */
  428. doeol(argc,argv)
  429. int argc;
  430. char *argv[];
  431. {
  432.     extern int unix_line_mode;
  433.  
  434.     if(argc < 2){
  435.         if(unix_line_mode)
  436.             printf("Unix\n");
  437.         else
  438.             printf("Standard\n");
  439.     } else {
  440.         if(strcmp(argv[1],"unix") == 0)
  441.             unix_line_mode = 1;
  442.         else if(strcmp(argv[1],"standard") == 0)
  443.             unix_line_mode = 0;
  444.         else {
  445.             return -1;
  446.         }
  447.     }
  448.     return 0;
  449. }
  450. /* Attach an interface
  451.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  452.  */
  453. doattach(argc,argv)
  454. int argc;
  455. char *argv[];
  456. {
  457.     extern struct cmds attab[];
  458.  
  459.     return subcmd(attab,argc,argv);
  460. }
  461. /* Manipulate I/O device parameters */
  462. doparam(argc,argv)
  463. int argc;
  464. char *argv[];
  465. {
  466.     register struct interface *ifp;
  467.  
  468.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  469.         if(strcmp(argv[1],ifp->name) == 0)
  470.             break;
  471.     }
  472.     if(ifp == NULLIF){
  473.         printf("Interface \"%s\" unknown\n",argv[1]);
  474.         return 1;
  475.     }
  476.     if(ifp->ioctl == NULLFP){
  477.         printf("Not supported\n");
  478.         return 1;
  479.     }
  480.     /* Pass rest of args to device-specific code */
  481.     return (*ifp->ioctl)(ifp,argc-2,argv+2);
  482. }
  483. /* Log messages of the form
  484.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  485.  */
  486. /*VARARGS2*/
  487. log(tcb,fmt,arg1,arg2,arg3,arg4)
  488. struct tcb *tcb;
  489. char *fmt;
  490. int arg1,arg2,arg3,arg4;
  491. {
  492.     char *cp;
  493.     long t;
  494.     int fd;
  495.  
  496.     if(logfp == NULLFILE)
  497.         return;
  498.     time(&t);
  499.     cp = ctime(&t);
  500.     rip(cp);
  501.     fprintf(logfp,"%s %s - ",cp,psocket(&tcb->conn.remote));
  502.     fprintf(logfp,fmt,arg1,arg2,arg3,arg4);
  503.     fprintf(logfp,"\n");
  504.     fflush(logfp);
  505. #ifdef    MSDOS
  506.     /* MS-DOS doesn't really flush files until they're closed */
  507.     fd = fileno(logfp);
  508.     if((fd = dup(fd)) != -1)
  509.         close(fd);
  510. #endif
  511. }
  512. /* Configuration-dependent code */
  513.  
  514. /* List of supported hardware devices */
  515. int ec_attach(),asy_attach(),pc_attach(),eg_attach(),hapn_attach(),at_attach(),
  516.     nr_attach(),pk_attach();
  517.  
  518. struct cmds attab[] = {
  519. #ifdef    PC_EC
  520.     /* 3-Com Ethernet interface */
  521.     "3c500", ec_attach, 7, 
  522.     "attach 3c500 <address> <vector> arpa <label> <buffers> <mtu>",
  523.     "Could not attach 3c500",
  524. #endif
  525. #ifdef    ASY
  526.     /* Ordinary PC asynchronous adaptor */
  527.     "asy", asy_attach, 8, 
  528.     "attach asy <address> <vector> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
  529.     "Could not attach asy",
  530. #endif
  531. #ifdef    PC100
  532.     /* PACCOMM PC-100 8530 HDLC adaptor */
  533.     "pc100", pc_attach, 8, 
  534.     "attach pc100 <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  535.     "Could not attach pc100",
  536. #endif
  537. #ifdef    EAGLE
  538.     /* EAGLE RS-232C 8530 HDLC adaptor */
  539.     "eagle", eg_attach, 8,
  540.     "attach eagle <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  541.     "Could not attach eagle",
  542. #endif
  543. #ifdef    HAPN
  544.     /* Hamilton Area Packet Radio (HAPN) 8273 HDLC adaptor */
  545.     "hapn", hapn_attach, 8,
  546.     "attach hapn <address> <vector> ax25 <label> <rx bufsize> <mtu> csma|full",
  547.     "Could not attach hapn",
  548. #endif
  549. #ifdef    APPLETALK
  550.     /* Macintosh AppleTalk */
  551.     "0", at_attach, 7,
  552.     "attach 0 <protocol type> <device> arpa <label> <rx bufsize> <mtu>",
  553.     "Could not attach Appletalk",
  554. #endif
  555. #ifdef NETROM
  556.     /* fake netrom interface */
  557.     "netrom", nr_attach, 1,
  558.     "attach netrom",
  559.     "Could not attach netrom",
  560. #endif
  561. #ifdef    PACKET
  562.     /* FTP Software's packet driver spec */
  563.     "packet", pk_attach, 4,
  564.     "attach packet <int#> <label> <buffers> <mtu>",
  565.     "Could not attach packet driver",
  566. #endif
  567.     NULLCHAR, NULLFP, 0,
  568.     "Unknown device",
  569.     NULLCHAR,
  570. };
  571.  
  572. /* Protocol tracing function pointers */
  573. #ifdef    TRACE
  574. int ax25_dump(),ether_dump(),ip_dump(),at_dump();
  575.  
  576. int (*tracef[])() = {
  577. #ifdef    AX25
  578.     ax25_dump,
  579. #else
  580.     NULLFP,
  581. #endif
  582.  
  583. #ifdef    ETHER
  584.     ether_dump,
  585. #else
  586.     NULLFP,
  587. #endif
  588.     ip_dump,
  589.  
  590. #ifdef    APPLETALK
  591.     at_dump,
  592. #else
  593.     NULLFP,
  594. #endif
  595. };
  596. #else
  597. int (*tracef[])() = { NULLFP };    /* No tracing at all */
  598. dump(interface,direction,type,bp)
  599. struct interface *interface;
  600. int direction;
  601. unsigned type;
  602. struct mbuf *bp;
  603. {
  604. }
  605. #endif
  606.  
  607. #ifdef    ASY
  608.  
  609. /* Attach a serial interface to the system
  610.  * argv[0]: hardware type, must be "asy"
  611.  * argv[1]: I/O address, e.g., "0x3f8"
  612.  * argv[2]: vector, e.g., "4"
  613.  * argv[3]: mode, may be:
  614.  *        "slip" (point-to-point SLIP)
  615.  *        "ax25" (AX.25 frame format in SLIP for raw TNC)
  616.  *        "nrs" (NET/ROM format serial protocol)
  617.  * argv[4]: interface label, e.g., "sl0"
  618.  * argv[5]: receiver ring buffer size in bytes
  619.  * argv[6]: maximum transmission unit, bytes
  620.  * argv[7]: interface speed, e.g, "9600"
  621.  * argv[8]: optional ax.25 callsign (NRS only)
  622.  */
  623. int
  624. asy_attach(argc,argv)
  625. int argc;
  626. char *argv[];
  627. {
  628.     register struct interface *if_asy;
  629.     extern struct interface *ifaces;
  630.     int16 dev;
  631.     int mode;
  632.     int asy_init();
  633.     int asy_send();
  634.     int asy_ioctl();
  635.     void doslip();
  636.     int asy_stop();
  637.     int ax_send();
  638.     int ax_output();
  639.     void kiss_recv();
  640.     int kiss_raw();
  641.     int kiss_ioctl();
  642.     int slip_send();
  643.     void slip_recv();
  644.     int slip_raw();
  645.     struct ax25_addr addr ;
  646.     int ax_send(),ax_output(),nrs_raw(),asy_ioctl();
  647.     void nrs_recv();
  648.  
  649.     if(nasy >= ASY_MAX){
  650.         printf("Too many asynch controllers\n");
  651.         return -1;
  652.     }
  653.     if(strcmp(argv[3],"slip") == 0)
  654.         mode = SLIP_MODE;
  655.     else if(strcmp(argv[3],"ax25") == 0)
  656.         mode = AX25_MODE;
  657.     else if(strcmp(argv[3],"nrs") == 0)
  658.         mode = NRS_MODE;
  659.     else 
  660.         mode = UNKNOWN;
  661.  
  662.     dev = nasy++;
  663.  
  664.     /* Create interface structure and fill in details */
  665.     if_asy = (struct interface *)calloc(1,sizeof(struct interface));
  666.     if_asy->name = malloc((unsigned)strlen(argv[4])+1);
  667.     strcpy(if_asy->name,argv[4]);
  668.     if_asy->mtu = atoi(argv[6]);
  669.     if_asy->dev = dev;
  670.     if_asy->recv = doslip;
  671.     if_asy->stop = asy_stop;
  672.  
  673.     switch(mode){
  674. #ifdef    SLIP
  675.     case SLIP_MODE:
  676.         if_asy->ioctl = asy_ioctl;
  677.         if_asy->send = slip_send;
  678.         if_asy->output = NULLFP;    /* ARP isn't used */
  679.         if_asy->raw = slip_raw;
  680.         if_asy->flags = 0;
  681.         slip[dev].recv = slip_recv;
  682.         break;
  683. #endif
  684. #ifdef    AX25
  685.     case AX25_MODE:  /* Set up a SLIP link to use AX.25 */
  686.         axarp();
  687.         if(mycall.call[0] == '\0'){
  688.             printf("set mycall first\n");
  689.             free(if_asy->name);
  690.             free((char *)if_asy);
  691.             nasy--;
  692.             return -1;
  693.         }
  694.         if_asy->ioctl = kiss_ioctl;
  695.         if_asy->send = ax_send;
  696.         if_asy->output = ax_output;
  697.         if_asy->raw = kiss_raw;
  698.         if(if_asy->hwaddr == NULLCHAR)
  699.             if_asy->hwaddr = malloc(sizeof(mycall));
  700.         memcpy(if_asy->hwaddr,(char *)&mycall,sizeof(mycall));
  701.         slip[dev].recv = kiss_recv;
  702.         break;
  703. #endif
  704. #ifdef    NRS
  705.     case NRS_MODE: /* Set up a net/rom serial interface */
  706.         if(argc < 9){
  707.             /* no call supplied? */
  708.             if(mycall.call[0] == '\0'){
  709.                 /* try to use default */
  710.                 printf("set mycall first or specify in attach statement\n");
  711.                 return -1;
  712.             } else
  713.                 addr = mycall;
  714.         } else {
  715.             /* callsign supplied on attach line */
  716.             if(setcall(&addr,argv[8]) == -1){
  717.                 printf ("bad callsign on attach line\n");
  718.                 free(if_asy->name);
  719.                 free((char *)if_asy);
  720.                 nasy--;
  721.                 return -1;
  722.             }
  723.         }
  724.         if_asy->recv = nrs_recv;
  725.         if_asy->ioctl = asy_ioctl;
  726.         if_asy->send = ax_send;
  727.         if_asy->output = ax_output;
  728.         if_asy->raw = nrs_raw;
  729.         if(if_asy->hwaddr == NULLCHAR)
  730.             if_asy->hwaddr = malloc(sizeof(addr));
  731.         memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
  732.         nrs[dev].iface = if_asy;
  733.         break;
  734. #endif
  735.     default:
  736.         printf("Mode %s unknown for interface %s\n",
  737.             argv[3],argv[4]);
  738.         free(if_asy->name);
  739.         free((char *)if_asy);
  740.         nasy--;
  741.         return -1;
  742.     }
  743.     if_asy->next = ifaces;
  744.     ifaces = if_asy;
  745.     asy_init(dev,argv[1],argv[2],(unsigned)atoi(argv[5]));
  746.     asy_speed(dev,atoi(argv[7]));
  747.     return 0;
  748. }
  749. #endif
  750. #ifndef    NETROM
  751. #ifdef    AX25
  752. struct ax25_addr nr_nodebc;
  753. #endif
  754. nr_route(bp)
  755. struct mbuf *bp;
  756. {
  757.     free_p(bp);
  758. }
  759. nr_nodercv(bp)
  760. {
  761.     free_p(bp);
  762. }
  763. #endif
  764.  
  765.  
  766. /* Display or set IP interface control flags */
  767. domode(argc,argv)
  768. int argc;
  769. char *argv[];
  770. {
  771.     register struct interface *ifp;
  772.  
  773.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  774.         if(strcmp(argv[1],ifp->name) == 0)
  775.             break;
  776.     }
  777.     if(ifp == NULLIF){
  778.         printf("Interface \"%s\" unknown\n",argv[1]);
  779.         return 1;
  780.     }
  781.     if(argc < 3){
  782.         printf("%s: %s\n",ifp->name,
  783.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  784.         return 0;
  785.     }
  786.     switch(argv[2][0]){
  787.     case 'v':
  788.     case 'c':
  789.     case 'V':
  790.     case 'C':
  791.         ifp->flags = CONNECT_MODE;
  792.         break;
  793.     case 'd':
  794.     case 'D':
  795.         ifp->flags = DATAGRAM_MODE;
  796.         break;
  797.     default:
  798.         printf("Usage: %s [vc | datagram]\n",argv[0]);
  799.         return 1;
  800.     }
  801.     return 0;
  802. }
  803.  
  804. #ifdef SERVERS
  805. dostart(argc,argv)
  806. int argc;
  807. char *argv[];
  808. {
  809.     return subcmd(startcmds,argc,argv);
  810. }
  811. dostop(argc,argv)
  812. int argc;
  813. char *argv[];
  814. {
  815.     return subcmd(stopcmds,argc,argv);
  816. }
  817. #endif SERVERS
  818.  
  819. #ifdef    TRACE
  820. static
  821. int
  822. dotrace(argc,argv)
  823. int argc;
  824. char *argv[];
  825. {
  826.     struct interface *ifp;
  827.  
  828.     if(argc < 2){
  829.         showtrace(&loopback);
  830.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  831.             showtrace(ifp);
  832.         return 0;
  833.     }
  834.     if(strcmp("loopback",argv[1]) == 0)
  835.         ifp = &loopback;
  836.     else 
  837.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  838.             if(strcmp(ifp->name,argv[1]) == 0)
  839.                 break;
  840.  
  841.     if(ifp == NULLIF){
  842.         printf("Interface %s unknown\n",argv[1]);
  843.         return 1;
  844.     }
  845.     if(argc >= 3)
  846.         ifp->trace = htoi(argv[2]);
  847.  
  848.     showtrace(ifp);
  849.     return 0;
  850. }
  851. /* Display the trace flags for a particular interface */
  852. static
  853. showtrace(ifp)
  854. register struct interface *ifp;
  855. {
  856.     if(ifp == NULLIF)
  857.         return;
  858.     printf("%s:",ifp->name);
  859.     if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
  860.         if(ifp->trace & IF_TRACE_IN)
  861.             printf(" input");
  862.         if(ifp->trace & IF_TRACE_OUT)
  863.             printf(" output");
  864.  
  865.         if(ifp->trace & IF_TRACE_HEX)
  866.             printf(" (Hex/ASCII dump)");
  867.         else if(ifp->trace & IF_TRACE_ASCII)
  868.             printf(" (ASCII dump)");
  869.         else
  870.             printf(" (headers only)");
  871.         printf("\n");
  872.     } else
  873.         printf(" tracing off\n");
  874.     fflush(stdout);
  875. }
  876. #endif
  877.  
  878. #ifndef    MSDOS
  879. static
  880. int
  881. doescape(argc,argv)
  882. int argc;
  883. char *argv[];
  884. {
  885.     if(argc < 2)
  886.         printf("0x%x\n",escape);
  887.     else 
  888.         escape = *argv[1];
  889.     return 0;
  890. }
  891. #endif    MSDOS
  892. static
  893. doremote(argc,argv)
  894. int argc;
  895. char *argv[];
  896. {
  897.     struct socket fsock,lsock;
  898.     struct mbuf *bp;
  899.  
  900.     lsock.address = ip_addr;
  901.     fsock.address = resolve(argv[1]);
  902.     lsock.port = fsock.port = atoi(argv[2]);
  903.     bp = alloc_mbuf(1);
  904.     if(strcmp(argv[3],"reset") == 0){
  905.         *bp->data = SYS_RESET;
  906.     } else if(strcmp(argv[3],"exit") == 0){
  907.         *bp->data = SYS_EXIT;
  908.     } else {
  909.         printf("Unknown command %s\n",argv[3]);
  910.         return 1;
  911.     }
  912.     bp->cnt = 1;
  913.     send_udp(&lsock,&fsock,0,0,bp,0,0,0);
  914.     return 0;
  915. }
  916.  
  917.